home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_138 / amigaline / amigaline4 < prev    next >
Text File  |  1992-05-06  |  5KB  |  175 lines

  1.             Technical Note #4
  2.           Stack, how to determine size at run time
  3.  
  4. SUMMARY
  5.  
  6. $ 4/0 Stack, how to determine size at run time
  7. $ release
  8. $ 26-Dec-87 Bryce Nesbitt / BDI
  9. $ stack, Workbench, CLI, process, startup
  10.  
  11.     It should be straightforward to determine the size of the stack your
  12. program is running on.    Sadly it is not.  This note should clear the
  13. confusion.
  14.  
  15. ----------------------------------------------------------------------------
  16.  
  17.     If your program needs more than the 4000 byte default stack, it has
  18.     some work to do.  It will need to check if the stack is large enough
  19.     for it's needs and take one of two actions if it is not:
  20.  
  21.     1.    Abort with an error requester.
  22.     2.    Allocate enough space and (using assembly language) point the stack
  23.     pointer to it.
  24.  
  25.  
  26. LANGUAGES
  27.  
  28.     Some languages will provide a global that you can look at to
  29.     determine the size of the current stack.  This is cleanest option, if
  30.     it is available to you.
  31.  
  32.     If there is any chance at all that user input may cause your
  33.     program to use more stack than normal, leave the stack checking option
  34.     of your compiler enabled.  Recursive functions are particularly
  35.     notorious stack blowers.
  36.  
  37.  
  38. WORKBENCH
  39.  
  40.     When stared from the Workbench tool, your stack size might have
  41.     come from one of three places:
  42.  
  43.     1.    The stack field of a Project icon.
  44.     2.    The stack field in your Tool's icon.
  45.     3.    The Workbench's default stack size.
  46.  
  47.     The icon that started you tool decides the stack size.    If the
  48.     stack field is blank, then the default of ~4000 bytes is used.  The
  49.     size is recorded in the normal task structures.
  50.  
  51.        If the user sets the stack size to an odd number then the Workbench
  52.     tool will crash, so don't worry about that situation.
  53.  
  54.  
  55. CLI
  56.  
  57.     When your code is started up it does NOT get a new process
  58.     invocation; as "CLI 3" your code is literally the same process that
  59.     runs CLI task 3.
  60.  
  61.     When the CLI starts up a program it allocates a brand new stack.
  62.     This is *not* the same stack the CLI itself uses.  The size of this
  63.     stack is *not* recorded in the normal "task" structure; it must be
  64.     extracted from the top of the stack at startup or from the
  65.     "cli_DefaultStack" field.
  66.  
  67.  
  68. ;-------------- ASSEMBLY EXAMPLE -----------
  69. ;
  70. ; 25-Jan-87  Bryce Nesbitt
  71. ;
  72. ; A complete startup module for assembly language programs.  Works from
  73. ; Workbench or CLI.
  74. ;
  75.     NOLIST
  76.     INCLUDE "exec/types.i"
  77.     INCLUDE "libraries/dosextens.i"
  78.     LIST
  79. jsrlib    MACRO
  80.     xref _LVO\1
  81.     jsr  _LVO\1(a6)
  82.     ENDM
  83. ;
  84. ; On startup (A7) contains a return address,
  85. ; 4(A7) contains the size of the stack in bytes
  86. ;
  87.         move.l    4(a7),d7            ;--Get CLI stack size--
  88.         move.l    4,a6            ;Get exec library pointer
  89.         suba.l    a1,a1            ;Put zero in A1
  90.         jsrlib    FindTask        ;Find this task
  91.         move.l    d0,a5
  92.         moveq    #0,d0            ;Set zero for later
  93.         move.l    pr_CLI(a5),d1       ;Check CLI/Workbench flag
  94.         bne.s    fromCLI
  95.  
  96.         move.l    pr_StackSize(a5),d7 ;--Get Workbench stack size--
  97.         lea.l    pr_MsgPort(a5),a0   ;Wait for the message
  98.         jsrlib    WaitPort        ; the Workbench will send
  99.         lea.l    pr_MsgPort(a5),a0
  100.         jsrlib    GetMsg
  101.  
  102. fromCLI     move.l    d0,-(a7)            ;Save the message, or zero
  103. ******************************************  A5-This task D7-Stack size
  104.  
  105.         ;...your code here...
  106.  
  107. ******************************************  D7-MUST contain result code
  108. ExitToDOS:    move.l    (a7)+,d2
  109.         beq.s    notWorkbench
  110.  
  111.         jsrlib    Forbid        ;Required so we won't be unloaded by
  112.         move.l    d2,a1        ; the Workbench too soon.
  113.         jsrlib    ReplyMsg    ;Reply to the Workbench message
  114.  
  115. notWorkbench    move.l    d7,d0        ;Return result code:
  116.         rts            ; 0 = ok       10 = error
  117.         END            ; 5 = warning  20 = severe failure
  118.  
  119.  
  120. ----------------- C EXAMPLE ----------------
  121. */
  122. /*
  123.  * stack_test.c  27-Oct-87.  Bryce Nesbitt
  124.  *
  125.  */
  126. #include "exec/types.h"
  127. #include "exec/tasks.h"
  128. #include "libraries/dosextens.h"
  129. #include "stdio.h"
  130. struct Process *FindTask();
  131.  
  132. void main()
  133. {
  134. register struct Process     *Process;
  135. register FILE            *Handle;
  136. struct CommandLineInterface *CLI;
  137.  
  138.     if (!(Handle=fopen("con:0/11/250/128/Stack Window","a")))
  139.     exit(20);       /* "a" is used so the window won't flicker */
  140.  
  141.     Process=FindTask(0L);
  142.  
  143.     if (CLI=(struct CommandLineInterface *)(Process->pr_CLI<<2))
  144.     {
  145.     if (CLI->cli_Background)
  146.         fprintf(Handle,"Background");
  147.     else
  148.         fprintf(Handle,"Foreground");
  149.     fprintf(Handle," CLI #%ld\n",Process->pr_TaskNum);
  150.  
  151.     fprintf(Handle,"Actual stack is: %ld\n\n",
  152.            CLI->cli_DefaultStack<<2);
  153.     }
  154.     else
  155.     {
  156.     fprintf(Handle,"This is not a CLI process\n");
  157.     fprintf(Handle,"Actual stack is %ld\n\n",Process->pr_StackSize);
  158.     }
  159.  
  160.     /* Other useless information (we already know the stack size) */
  161.     fprintf(Handle,"pr_StackSize     %ld\n",Process->pr_StackSize);
  162.     fprintf(Handle,"pr_StackBase     $%lx\n\n",Process->pr_StackBase<<2);
  163.     fprintf(Handle,"tc_SPLower       $%lx\n",Process->pr_Task.tc_SPLower);
  164.     fprintf(Handle,"tc_SPUpper       $%lx\n",Process->pr_Task.tc_SPUpper);
  165.     fprintf(Handle,"Upper-Lower      %ld\n\n",
  166.        (long)Process->pr_Task.tc_SPUpper-
  167.        (long)Process->pr_Task.tc_SPLower);
  168.     fprintf(Handle,"tc_SPReg         $%lx\n",Process->pr_Task.tc_SPReg);
  169.  
  170.     Delay(80L);     /* Be quick :-).  BTW: *Never* Delay(0L);! */
  171.     fprintf(Handle,"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  172.             /* Dramatic exit :-) */
  173.     fclose(Handle);
  174. }
  175.